package cn.edu.cdu.farmdeal.service.impl;

import cn.edu.cdu.farmdeal.domain.*;
import cn.edu.cdu.farmdeal.form.SuggestForm;
import cn.edu.cdu.farmdeal.mapper.*;
import cn.edu.cdu.farmdeal.service.IndexService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

/**
 * @Author: tupeng
 * @Date: 2020/3/13
 **/
@Service
public class IndexServiceImpl implements IndexService {
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private MiaoshaMapper miaoshaMapper;
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private UserInfMapper userInfMapper;
    @Autowired
    private UserProductMapper userProductMapper;
    @Autowired
    private OrderMapper orderMapper;

    @Override
    public int getOrderNum(String userName) {
        return orderMapper.getOrderNum(userName);
    }

    @Override
    public List<Product> getRecommend(String userId) {
        //根据用户账号获取id
        UserInfExample userInfExample = new UserInfExample();
        userInfExample.createCriteria().andUseridEqualTo(userId);
        List<UserInf> userInfs = userInfMapper.selectByExample(userInfExample);
        //获得ID（int）
        int userid = userInfs.get(0).getUserInfoId();
        return recommend(userid);
    }

    /**
     * 通过计算余弦相似度并取TopN, 返回为userid的用户生成的5个推荐产品
     */
    public List<Product> recommend(int userid) {
        //定义其他用户下的订单
        List<UserProduct> userProducts;
        //获得所有用户列表
        List<UserInf> userInfs = userInfMapper.getAllUsers();
        //获得所有的订单
        List<Product> products = productMapper.getAllProduct();
        //定义当前矩阵
        int[][] curMatrix = new int[products.size() + 5][products.size() + 5];
        //定义共现矩阵
        int[][] comMatrix = new int[products.size() + 5][products.size() + 5];
        //对每个产品下单的人数
        int[] N = new int[products.size() + 5];
        for (UserInf userInf : userInfs) {
            //当前用户跳过
            if (userInf.getUserInfoId() == userid) {
                continue;
            }
            //其他用户下过订单的产品
            UserProductExample userProductExample = new UserProductExample();
            userProductExample.createCriteria().andUserInfoIdEqualTo(userInf.getUserInfoId());
            userProducts = userProductMapper.selectByExample(userProductExample);
            for (int i = 0; i < products.size(); i++) {
                for (int j = 0; j < products.size(); j++) {
                    //清空矩阵
                    curMatrix[i][j] = 0;
                }
            }
            for (int i = 0; i < userProducts.size(); i++) {
                int pid1 = userProducts.get(i).getProductId();
                //计算每个用户有多少的订单
                ++N[pid1];
                for (int j = i + 1; j < userProducts.size(); j++) {
                    int pid2 = userProducts.get(j).getProductId();
                    ++curMatrix[pid1][pid2];
                    //两两加一
                    ++curMatrix[pid2][pid1];
                }
            }
            //累加所有矩阵, 得到共现矩阵
            for (int i = 0; i < products.size(); i++) {
                for (int j = 0; j < products.size(); j++) {
                    int pid1 = products.get(i).getId(), pid2 = products.get(j).getId();
                    comMatrix[pid1][pid2] += curMatrix[pid1][pid2];
                    comMatrix[pid1][pid2] += curMatrix[pid1][pid2];
                }
            }
        }
        //预处理的列表
        TreeSet<Product> preList = new TreeSet<Product>(new Comparator<Product>() {
            @Override
            public int compare(Product o1, Product o2) {
                if (o1.getW() != o2.getW()) {
                    return (int) (o1.getW() - o2.getW()) * 100;
                } else {
                    return o1.getCnt() - o2.getCnt();
                }
            }
        });
        //当前用户下单的产品列表
        UserProductExample userProductExample = new UserProductExample();
        userProductExample.createCriteria().andUserInfoIdEqualTo(userid);
        userProducts = userProductMapper.selectByExample(userProductExample);
        //判重数组
        boolean[] used = new boolean[products.size() + 5];

        for (UserProduct userProduct : userProducts) {
            //既喜欢i又喜欢j的人数
            int Nij = 0;
            //相似度
            double Wij;
            //当前的产品
            Product tmp;
            int i = userProduct.getProductId();
            for (Product product : products) {
                if (userProduct.getProductId().equals(product.getId())) {
                    continue;
                }
                int j = product.getId();

                Nij = comMatrix[i][j];
                //计算余弦相似度
                Wij = (double) Nij / Math.sqrt(N[i] * N[j]);
                ProductExample productExample = new ProductExample();
                productExample.createCriteria().andIdEqualTo(product.getId());
                List<Product> products1 = productMapper.selectByExample(productExample);
                tmp = products1.get(0);
                tmp.setW(Wij);
                if (used[tmp.getId()]) {
                    continue;
                }
                preList.add(tmp);
                used[tmp.getId()] = true;
            }
        }
        //生成的推荐结果
        List<Product> recomLists = new ArrayList<>();
        for (int i = 0; preList.size() > 0 && i < 5; i++) {
            recomLists.add(preList.pollLast());
            preList.pollLast();
        }
        if (recomLists.size() <= 5) {
            //推荐数量不满5个, 补足销量最高的产品数
            int tmpSize= recomLists.size();
            List<Product> products1 = productMapper.getMostSale();
            while (recomLists.size()<5){
                for (int i = 0; i < products1.size(); i++) {
                    if (isExist(recomLists, products1.get(i).getId())) {
                        recomLists.add(products1.get(i));
                        if(recomLists.size()==5){
                            break;
                        }
                    }
                }
            }

        }
        return recomLists;
    }
    /**
     * 判断是否存在该产品
     * @param products
     * @param pid
     * @return
     */
    public boolean isExist(List<Product> products, int pid) {
        for (Product product : products) {
            if (product.getId() == pid) {
                return false;
            }
        }
        return true;
    }

    @Override
    public List<SuggestForm> getSuggest(String InputValue) {
        return productMapper.getSuggest(InputValue);
    }

    @Override
    public List<Product> getMiaosha() {
        List<Product> productList = new ArrayList<>();
//        ProductExample productExample = new ProductExample();
//        productExample.createCriteria().andIsMiaoshaEqualTo("1");
        //设置保留位数
        DecimalFormat df = new DecimalFormat("0");
        List<Product> userInfList = productMapper.getMiaosha();
        for (Product product : userInfList) {
            String stock = product.getStock();
            int stock1 = Integer.parseInt(stock);
            if(!"".equals(product.getSaleNum())){
                int saleNum = Integer.parseInt(product.getSaleNum());
                String progress = df.format((float) saleNum / stock1 * 50);
                product.setProgress(progress);
            }
            productList.add(product);
        }
        return productList;
    }

    @Override
    public Miaosha getMsTime() {
        MiaoshaExample miaoshaExample = new MiaoshaExample();
        miaoshaExample.createCriteria().andIdEqualTo(1);
        List<Miaosha> miaoshas = miaoshaMapper.selectByExample(miaoshaExample);
        return miaoshas.get(0);
    }

    @Override
    public List<Product> getHotSale() {
        return productMapper.getHotSale();
    }

    @Override
    public int getCartNum(String userName) {
        return cartMapper.getCartNum(userName);
    }
}
